//TODO: implement, Compass Edge-Detector

using System;
using System.Drawing;
using System.Drawing.Imaging;

namespace LowLevelGraphics.Filter
{

    /// <summary>
    /// Compass is an algorithm to apply the compass edge detector to an image
    /// </summary>
    public class Compass : BaseImageFilter
    {

        //  //the Convolution operator used as part of the process.

        //  Convolution convolution;

        //  //the width and height of the output image

        private int d_w = 0;
        private int d_h = 0;
        private int[] dest_1d = null;
        private int[] label_1d = null;

          //Create a new version of twoimages to put the output images in

          //TwoImages twoimages = new TwoImages();

          //The following are all the kernels that could be applied to the image

        //The prewitt kernels
        private int[,] prewitt3 = new int[,] { { -1, 1, 1 }, { -1, -2, 1 }, { -1, 1, 1 } };
        private int[,] prewitt4 = new int[,] { { 1, 1, 1 }, { -1, -2, 1 }, { -1, -1, 1 } };
        private int[,] prewitt5 = new int[,] { { 1, 1, 1 }, { 1, -2, 1 }, { -1, -1, -1 } };
        private int[,] prewitt6 = new int[,] { { 1, 1, 1 }, { 1, -2, -1 }, { 1, -1, -1 } };
        private int[,] prewitt7 = new int[,] { { 1, 1, -1 }, { 1, -2, -1 }, { 1, 1, -1 } };
        private int[,] prewitt8 = new int[,] { { 1, -1, -1 }, { 1, -2, -1 }, { 1, 1, 1 } };
        private int[,] prewitt1 = new int[,] { { -1, -1, -1 }, { 1, -2, 1 }, { 1, 1, 1 } };
        private int[,] prewitt2 = new int[,] { { -1, -1, 1 }, { -1, -2, 1 }, { 1, 1, 1 } };

        //The sobel kernels 
        private int[,] sobel3 = new int[,] { { -1, 0, 1 }, { -2, 0, 2 }, { -1, 0, 1 } };
        private int[,] sobel4 = new int[,] { { 0, 1, 2 }, { -1, 0, 1 }, { -2, -1, 0 } };
        private int[,] sobel5 = new int[,] { { 1, 2, 1 }, { 0, 0, 0 }, { -1, -2, -1 } };
        private int[,] sobel6 = new int[,] { { 2, 1, 0 }, { 1, 0, -1 }, { 0, -1, -2 } };
        private int[,] sobel7 = new int[,] { { 1, 0, -1 }, { 2, 0, -2 }, { 1, 0, -1 } };
        private int[,] sobel8 = new int[,] { { 0, -1, -2 }, { 1, 0, -1 }, { 2, 1, 0 } };
        private int[,] sobel1 = new int[,] { { -1, -2, -1 }, { 0, 0, 0 }, { 1, 2, 1 } };
        private int[,] sobel2 = new int[,] { { -2, -1, 0 }, { -1, 0, 1 }, { 0, 1, 2 } };

        //The kirsch kernels
        private int[,] kirsch3 = new int[,] { { -3, -3, 5 }, { -3, 0, 5 }, { -3, -3, 5 } };
        private int[,] kirsch4 = new int[,] { { -3, 5, 5 }, { -3, 0, 5 }, { -3, -3, -3 } };
        private int[,] kirsch5 = new int[,] { { 5, 5, 5 }, { -3, 0, -3 }, { -3, -3, -3 } };
        private int[,] kirsch6 = new int[,] { { 5, 5, -3 }, { 5, 0, -3 }, { -3, -3, -3 } };
        private int[,] kirsch7 = new int[,] { { 5, -3, -3 }, { 5, 0, -3 }, { 5, -3, -3 } };
        private int[,] kirsch8 = new int[,] { { -3, -3, -3 }, { 5, 0, -3 }, { 5, 5, -3 } };
        private int[,] kirsch1 = new int[,] { { -3, -3, -3 }, { -3, 0, -3 }, { 5, 5, 5 } };
        private int[,] kirsch2 = new int[,] { { -3, -3, -3 }, { -3, 0, 5 }, { -3, 5, 5 } };

        //The robinson kernels 
        private int[,] robinson3 = new int[,] { { -1, 0, 1 }, { -1, 0, 1 }, { -1, 0, 1 } };
        private int[,] robinson4 = new int[,] { { 0, 1, 1 }, { -1, 0, 1 }, { -1, -1, 0 } };
        private int[,] robinson5 = new int[,] { { 1, 1, 1 }, { 0, 0, 0 }, { -1, -1, -1 } };
        private int[,] robinson6 = new int[,] { { 1, 1, 0 }, { 1, 0, -1 }, { 0, -1, -1 } };
        private int[,] robinson7 = new int[,] { { 1, 0, -1 }, { 1, 0, -1 }, { 1, 0, -1 } };
        private int[,] robinson8 = new int[,] { { 0, -1, -1 }, { 1, 0, -1 }, { 1, 1, 0 } };
        private int[,] robinson1 = new int[,] { { -1, -1, -1 }, { 0, 0, 0 }, { 1, 1, 1 } };
        private int[,] robinson2 = new int[,] { { -1, -1, 0 }, { -1, 0, 1 }, { 0, 1, 1 } };

        /// <summary>
        /// default constructor
        /// </summary>
        public Compass()
        {
        }

        /// <summary>
        /// used by clone to create a deep copy
        /// </summary>
        /// <param name="_compass"></param>
        internal Compass(Compass _compass)
        {
        }

        /// <summary>
        /// executes this filter
        /// </summary>
        /// <param name="_bitmap"></param>
        /// <returns></returns>
        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {
            Apply_Compass(_bitmap, _bitmap.Width, _bitmap.Height, 0, true, 1.0f, 0);
            return _bitmap;
        }

        /// <summary>
        /// Applies the compass edge detector to the input image
        /// Tim's Compass Edge Detection Algorithm
        /// a) assume the image is grey level (hence RR=GG=BB)
        /// b) use value <!-- &0x000000ff to get the BB value --> 
        /// c) apply each kernel to a point in the array
        /// d) find kernel with maximum response and set as edge magnitude
        /// e) set pixel label
        ///
        /// </summary>
        /// <param name="src_1d">The source image as a pixel array</param>
        /// <param name="width">width of the destination image in pixels</param>
        /// <param name="height">height of the destination image in pixels</param>
        /// <param name="kertype">kertype The type of kernel to be applied</param>
        /// <param name="coloured">coloured Is the labelling image to be in colour or not</param>
        /// <param name="scale">A scale factor to be applied to the image</param>
        /// <param name="offset">An offset to be added to the image</param>
        /// <returns>An object containing the two output images</returns>
        private void Apply_Compass(UnsafeBitmap _bitmap, int width, int height, int kertype,
                       bool coloured, float scale, int offset)
        {
            UnsafeBitmap bitmap = _bitmap;
            UnsafeBitmap bitmapCloned = (UnsafeBitmap)_bitmap.Clone();
            d_w = width;
            d_h = height;
            int result = 0, max = 0, mag = 0;
            max = 0;

            //For kernel type prewitt and greyscale labelling
            if (kertype == 0 && coloured == false)
            {
                for (int i = 1; i < (d_w - 1); i++)
                {
                    for (int j = 1; j < (d_h - 1); j++)
                    {
                        try
                        {
                            max = 0;
                            //Apply a convolution
                            mag = new CNewImageFilters(new ConvolutionMatrixCustom(prewitt1)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                            //Check if it beats current max
                            if (mag > max)
                            {
                                max = mag;
                                //If it does then set as current max, and change the pixel label
                                bitmap.SetPixel(i, j - 1, Color.FromArgb(unchecked((int)(0xFF << 24 | 0 << 16 | 0 << 8 | 0))));
                            }
                            mag = new CNewImageFilters(new ConvolutionMatrixCustom(prewitt2)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                            if (mag > max)
                            {
                                max = mag;
                                bitmap.SetPixel(i, j - 1, Color.FromArgb(unchecked((int)(0xFF << 24 | 36 << 16 | 36 << 8 | 36))));
                            }
                            mag = new CNewImageFilters(new ConvolutionMatrixCustom(prewitt3)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                            if (mag > max)
                            {
                                max = mag;
                                bitmap.SetPixel(i, j - 1, Color.FromArgb(unchecked((int)(0xFF << 24 | 72 << 16 | 72 << 8 | 72))));
                            }
                            mag = new CNewImageFilters(new ConvolutionMatrixCustom(prewitt4)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                            if (mag > max)
                            {
                                max = mag;
                                bitmap.SetPixel(i, j - 1, Color.FromArgb(unchecked((int)(0xFF << 24 | 108 << 16 | 108 << 8 | 108))));
                            }
                            mag = new CNewImageFilters(new ConvolutionMatrixCustom(prewitt5)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                            if (mag > max)
                            {
                                max = mag;
                                bitmap.SetPixel(i, j - 1, Color.FromArgb(unchecked((int)(0xFF << 24 | 144 << 16 | 144 << 8 | 144))));
                            }
                            mag = new CNewImageFilters(new ConvolutionMatrixCustom(prewitt6)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                            if (mag > max)
                            {
                                max = mag;
                                bitmap.SetPixel(i, j - 1, Color.FromArgb(unchecked((int)(0xFF << 24 | 180 << 16 | 180 << 8 | 180))));
                            }
                            mag = new CNewImageFilters(new ConvolutionMatrixCustom(prewitt7)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                            if (mag > max)
                            {
                                max = mag;
                                bitmap.SetPixel(i, j - 1, Color.FromArgb(unchecked((int)(0xFF << 24 | 216 << 16 | 216 << 8 | 216))));
                            }
                            mag = new CNewImageFilters(new ConvolutionMatrixCustom(prewitt8)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                            if (mag > max)
                            {
                                max = mag;
                                bitmap.SetPixel(i, j - 1, Color.FromArgb(unchecked((int)(0xff << 25 | 252 << 16 | 252 << 8 | 252))));
                            }
                            //Scale and offset
                            max = offset + (int)(max * scale);
                            //Clip values
                            if (max > 255)
                            {
                                max = 255;
                            }
                            if (max < 0)
                            {
                                max = 0;
                            }
                            bitmap.SetPixel(i, j - 1, Color.FromArgb((int)(0xFF << 24 | max << 16 | max << 8 | max))); // Original Code (0xFF << 24 | max << 16 | max << 8 | max)
                        }
                        catch { }
                    }
                }
            }

            //For kernel type prewitt and colour labelling
            if (kertype == 0 && coloured == true)
            {
                for (int i = 1; i < (d_w - 1); i++)
                {
                    for (int j = 1; j < (d_h - 1); j++)
                    {
                        try
                        {
                            max = 0;
                            mag = new CNewImageFilters(new ConvolutionMatrixCustom(prewitt1)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                            if (mag > max)
                            {
                                max = mag;
                                bitmap.SetPixel(i, j - 1, Color.Black);
                            }
                            mag = new CNewImageFilters(new ConvolutionMatrixCustom(prewitt2)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                            if (mag > max)
                            {
                                max = mag;
                                bitmap.SetPixel(i, j - 1, Color.Blue);
                            }
                            mag = new CNewImageFilters(new ConvolutionMatrixCustom(prewitt3)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                            if (mag > max)
                            {
                                max = mag;
                                bitmap.SetPixel(i, j - 1, Color.Green);
                            }
                            mag = new CNewImageFilters(new ConvolutionMatrixCustom(prewitt4)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                            if (mag > max)
                            {
                                max = mag;
                                bitmap.SetPixel(i, j - 1, Color.Orange);
                            }
                            mag = new CNewImageFilters(new ConvolutionMatrixCustom(prewitt5)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                            if (mag > max)
                            {
                                max = mag;
                                bitmap.SetPixel(i, j - 1, Color.Red);
                            }
                            mag = new CNewImageFilters(new ConvolutionMatrixCustom(prewitt6)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                            if (mag > max)
                            {
                                max = mag;
                                bitmap.SetPixel(i, j - 1, Color.White);
                            }
                            mag = new CNewImageFilters(new ConvolutionMatrixCustom(prewitt7)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                            if (mag > max)
                            {
                                max = mag;
                                bitmap.SetPixel(i, j - 1, Color.Yellow);
                            }
                            mag = new CNewImageFilters(new ConvolutionMatrixCustom(prewitt8)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                            if (mag > max)
                            {
                                max = mag;
                                bitmap.SetPixel(i, j - 1, Color.Magenta);
                            }
                            max = offset + (int)(max * scale);
                            if (max > 255)
                            {
                                max = 255;
                            }
                            if (max < 0)
                            {
                                max = 0;
                            }
                            bitmap.SetPixel(i, j - 1, Color.FromArgb(unchecked((int)(0xFF << 24 | max << 16 | max << 8 | max))));
                        }
                        catch { }
                    }
                }
            }


            //For kernel type sobel and greyscale labelling
            if (kertype == 1 && coloured == false)
            {
                for (int i = 1; i < (d_w - 1); i++)
                {
                    for (int j = 1; j < (d_h - 1); j++)
                    {
                        max = 0;
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(sobel1)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.FromArgb(unchecked((int)(0xFF << 24 | 0 << 16 | 0 << 8 | 0))));
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(sobel2)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.FromArgb(unchecked((int)( 0xFF << 24 | 36 << 16 | 36 << 8 | 36))));
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(sobel3)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.FromArgb(unchecked((int)(0xFF << 24 | 72 << 16 | 72 << 8 | 72))));
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(sobel4)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.FromArgb(unchecked((int)( 0xFF << 24 | 108 << 16 | 108 << 8 | 108))));
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(sobel5)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.FromArgb(unchecked((int)( 0xFF << 24 | 144 << 16 | 144 << 8 | 144))));
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(sobel6)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.FromArgb(unchecked((int)( 0xFF << 24 | 180 << 16 | 180 << 8 | 180))));
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(sobel7)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.FromArgb(unchecked((int)( 0xFF << 24 | 216 << 16 | 216 << 8 | 216))));
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(sobel8)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.FromArgb(unchecked((int)( 0xFF << 24 | 252 << 16 | 252 << 8 | 252))));
                        }
                        max = offset + (int)(max * scale);
                        if (max > 255)
                        {
                            max = 255;
                        }
                        if (max < 0)
                        {
                            max = 0;
                        }
                        bitmap.SetPixel(i ,j - 1, Color.FromArgb(unchecked((int)( 0xFF << 24 | max << 16 | max << 8 | max))));
                    }
                }
            }

            //For kernel type sobel and colour labelling
            if (kertype == 1 && coloured == true)
            {
                for (int i = 1; i < (d_w - 1); i++)
                {
                    for (int j = 1; j < (d_h - 1); j++)
                    {
                        max = 0;
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(sobel1)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.Black);
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(sobel2)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.Blue);
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(sobel3)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.Green);
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(sobel4)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.Orange);
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(sobel5)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.Red);
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(sobel6)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.White);
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(sobel7)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.Yellow);
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(sobel8)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.Magenta);
                        }
                        max = offset + (int)(max * scale);
                        if (max > 255)
                        {
                            max = 255;
                        }
                        if (max < 0)
                        {
                            max = 0;
                        }
                        bitmap.SetPixel(i, j - 1, Color.FromArgb(unchecked((int)0xFF << 24 | max << 16 | max << 8 | max)));
                    }
                }
            }

            //For kernel type kirsch and greyscale labelling
            if (kertype == 2 && coloured == false)
            {
                for (int i = 1; i < (d_w - 1); i++)
                {
                    for (int j = 1; j < (d_h - 1); j++)
                    {
                        max = 0;
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(kirsch1)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.FromArgb(unchecked((int)( 0xFF << 24 | 0 << 16 | 0 << 8 | 0))));
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(kirsch2)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.FromArgb(unchecked((int)( 0xFF << 24 | 36 << 16 | 36 << 8 | 36))));
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(kirsch3)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.FromArgb(unchecked((int)( 0xFF << 24 | 72 << 16 | 72 << 8 | 72))));
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(kirsch4)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.FromArgb(unchecked((int)( 0xFF << 24 | 108 << 16 | 108 << 8 | 108))));
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(kirsch5)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.FromArgb(unchecked((int)( 0xFF << 24 | 144 << 16 | 144 << 8 | 144))));
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(kirsch6)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.FromArgb(unchecked((int)( 0xFF << 24 | 180 << 16 | 180 << 8 | 180))));
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(kirsch7)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.FromArgb(unchecked((int)( 0xFF << 24 | 216 << 16 | 216 << 8 | 216))));
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(kirsch8)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.FromArgb(unchecked((int)( 0xFF << 24 | 252 << 16 | 252 << 8 | 252))));
                        }
                        max = offset + (int)(max * scale);
                        if (max > 255)
                        {
                            max = 255;
                        }
                        if (max < 0)
                        {
                            max = 0;
                        }
                        bitmap.SetPixel(i, j - 1, Color.FromArgb( (int)(0xFF << 24 | max << 16 | max << 8 | max)));
                    }
                }
            }

            //For kernel type kirsch and colour labelling
            if (kertype == 2 && coloured == true)
            {
                for (int i = 1; i < (d_w - 1); i++)
                {
                    for (int j = 1; j < (d_h - 1); j++)
                    {
                        max = 0;
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(kirsch1)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.Black);
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(kirsch2)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.Blue);
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(kirsch3)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.Green);
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(kirsch4)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.Orange);
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(kirsch5)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.Red);
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(kirsch6)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.White);
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(kirsch7)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.Yellow);
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(kirsch8)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.Magenta);
                        }
                        max = offset + (int)(max * scale);
                        if (max > 255)
                        {
                            max = 255;
                        }
                        if (max < 0)
                        {
                            max = 0;
                        }
                        bitmap.SetPixel(i, j - 1,Color.FromArgb((int)(0xFF << 24 | max << 16 | max << 8 | max)));
                    }
                }
            }


        //    //For kernel type robinson and greyscale labelling
            if (kertype == 3 && coloured == false)
            {
                for (int i = 1; i < (d_w - 1); i++)
                {
                    for (int j = 1; j < (d_h - 1); j++)
                    {
                        max = 0;
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(robinson1)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.FromArgb(unchecked((int)( 0xFF << 24 | 0 << 16 | 0 << 8 | 0))));
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(robinson2)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.FromArgb(unchecked((int)(0xFF << 24 | 36 << 16 | 36 << 8 | 36))));
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(robinson3)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.FromArgb(unchecked((int)(0xFF << 24 | 72 << 16 | 72 << 8 | 72))));
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(robinson4)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.FromArgb(unchecked((int)(0xFF << 24 | 108 << 16 | 108 << 8 | 108))));
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(robinson5)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.FromArgb(unchecked((int)(0xFF << 24 | 144 << 16 | 144 << 8 | 144))));
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(robinson6)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.FromArgb(unchecked((int)(0xFF << 24 | 180 << 16 | 180 << 8 | 180))));
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(robinson7)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1, Color.FromArgb(unchecked((int)(0xFF << 24 | 216 << 16 | 216 << 8 | 216))));
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(robinson8)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i, j - 1, Color.FromArgb(unchecked((int)(0xFF << 24 | 252 << 16 | 252 << 8 | 252))));
                        }
                        max = offset + (int)(max * scale);
                        if (max > 255)
                        {
                            max = 255;
                        }
                        if (max < 0)
                        {
                            max = 0;
                        }
                        bitmap.SetPixel(i, j - 1, Color.FromArgb(unchecked((int)( 0xFF << 24 | max << 16 | max << 8 | max))));
                    }
                }
            }

            //For kernel type robinson and colour labelling
            if (kertype == 3 && coloured == true)
            {
                for (int i = 1; i < (d_w - 1); i++)
                {
                    for (int j = 1; j < (d_h - 1); j++)
                    {
                        max = 0;
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(robinson1)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1,  Color.Black);
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(robinson2)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1,  Color.Blue);
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(robinson3)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1,  Color.Green);
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(robinson4)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1,  Color.Orange);
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(robinson5)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1,  Color.Red);
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(robinson6)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1,  Color.White);
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(robinson7)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1,  Color.Yellow);
                        }
                        mag = new CNewImageFilters(new ConvolutionMatrixCustom(robinson8)).ApplyConvolution(bitmapCloned, i - 1, j - 1);
                        if (mag > max)
                        {
                            max = mag;
                            bitmap.SetPixel(i,  j - 1,  Color.Magenta);
                        }
                        max = offset + (int)(max * scale);
                        if (max > 255)
                        {
                            max = 255;
                        }
                        if (max < 0)
                        {
                            max = 0;
                        }
                        bitmap.SetPixel(i , j - 1, Color.FromArgb( (int)(0xFF << 24 | max << 16 | max << 8 | max)));
                    }
                }
            }

        //    //Set the output images of the return class
        //    twoimages.image1 = dest_1d;
        //    twoimages.image2 = label_1d;

            bitmapCloned.Dispose();
        //    return twoimages;
        }

        /// <summary>
        /// Create a deep copy
        /// </summary>
        /// <returns></returns>
        public override object Clone()
        {
            return new Compass(this);
        }
    }
}